package jdbc.pstmt;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import jdbc.pstmt.hr.domain.Department;

public class PreparedStatementTest {
	
	static String driverClass = "oracle.jdbc.driver.OracleDriver";
	static String url = "jdbc:oracle:thin:@127.0.0.1:1521:XE";
	static String user = "scott";
	static String password = "tiger";
	
	public static void main(String[] args) throws SQLException{
		try {
			Class.forName(driverClass);
		} catch (ClassNotFoundException e) {
			// 이놈은 또 뭐냐? 뭔지 알아보자. 
			e.printStackTrace();
			return;
		}
		//insert처리
		//insertDepartment("d-800", "정진영", "서울");
		//insertDepartment("d-801", "김철수", "부산");
		//insertDepartment("d-802", "문수정", "수원");
		
		//Department dd= new Department("d-100","최효근","강남");
		//insertDepartment(dd);
		
		//int cnt = deleteDepartmentById("d-82");
		//System.out.println(cnt+"개 부서 삭제");
		
	//	updateDepartmentById(new Department("d-82","박태규","마산"));
//		Department dept = selectDepartmentById("d-2");
//		if(dept != null){
//			System.out.println(dept);
//		}else{
//			System.out.println("d-2인 부서는 없습니다.");
//		}
		
		System.out.println("----------------전체 부서 조회-------------------");
		ArrayList<Department> list = selectDepartmentList();
		if(list.size() == 0){
			System.out.println("등록된 부서가 없습니다.");
		}else{
			for(Department d : list){
				System.out.println(d);
			}
		}
		
		
	}
	
	//똑같은 메소드인데 이렇게 쓰는게 맞다. 비교해보자. 
	public static int  insertDepartment(Department dept) throws SQLException {
		String sql = "insert into department values(?,?,?)";//이 괄호 안에 벨류 값을 넣는건 의미가 없지, 매개변수로 받아서 써야 의미가 있지.
		//저 물음표는 뭔 값이 들어갈진 모르겠지만 하여간 값 3개가 들어갈것이라는 일종의 예고
		Connection conn = null;
		PreparedStatement pstmt = null;
		int count = -1;// 이놈은 뭐지?
		
		try{
			//1. connection
			conn = DriverManager.getConnection(url,user,password);
			//2.PreparedStatement 생성
			pstmt = conn.prepareStatement(sql);
			//2-2 ?에 값을 치환하는 작업이 필요하다. 
			pstmt.setString(1, dept.getDepartmentId());
			pstmt.setString(2, dept.getDepartmentName());
			pstmt.setString(3, dept.getLocation());
			//3. 쿼리문 전송
			count = pstmt.executeUpdate();//이놈은 뭐지??
			return count;//? 뭐지??
		
		}finally {
			//4. close
			if(pstmt != null)pstmt.close();
			if(conn != null)conn.close();
		}
	}
	
	//쿼리문을 편하게 넣는 메소드를 만들려고 한다.
	public static int  insertDepartment(String id, String name, String loc) throws SQLException {
		String sql = "insert into department values(?,?,?)";//이 괄호 안에 벨류 값을 넣는건 의미가 없지, 매개변수로 받아서 써야 의미가 있지.
		//저 물음표는 뭔 값이 들어갈진 모르겠지만 하여간 값 3개가 들어갈것이라는 일종의 예고
		Connection conn = null;
		PreparedStatement pstmt = null;
		int count = -1;// 이놈은 뭐지?
		
		try{
			//1. connection
			conn = DriverManager.getConnection(url,user,password);
			//2.PreparedStatement 생성
			pstmt = conn.prepareStatement(sql);
			//2-2 ?에 값을 치환하는 작업이 필요하다. 
			pstmt.setString(1, id);
			pstmt.setString(2, name);
			pstmt.setString(3, loc);
			//3. 쿼리문 전송
			count = pstmt.executeUpdate();//이놈은 뭐지??
			return count;//? 뭐지??
		
		}finally {
			//4. close
			if(pstmt != null)pstmt.close();
			if(conn != null)conn.close();
		}
	}
	
	//매개 변수로 받은 부서아이디로 부서정보 delete 처리
	public static int deleteDepartmentById(String departmentId) throws SQLException{
		String sql = "delete from department where department_id = ?";
		Connection conn = null;
		PreparedStatement pstmt = null;
		//int count = -1;
		
		try{
			//연결
			conn = DriverManager.getConnection(url,user,password);
			//PreparedStatement 생성
			pstmt = conn.prepareStatement(sql);
			//?에 값 치환
			pstmt.setString(1, departmentId);
			//쿼리 실행
			//count = pstmt.executeUpdate();
			//return count;
			//이렇게 카운트에 pstmt.executeUpdate(); 이걸 넣거나 
			return pstmt.executeUpdate();
			
		}finally {
			if(pstmt != null) pstmt.close();
			if(conn != null) conn.close();
		}
		
	}
//		매개변수로 수정할 부서의정보를 Department로 받아서 부서_ID를 기준으로 나머지 컬럼값들 수정 처리(부서명과 위치만 수정)
		public static int updateDepartmentById(Department dept) throws SQLException {
			String sql = "update department set department_name = ?, location = ? where department_id = ?";
			Connection conn = null;
			PreparedStatement pstmt = null;
			
			try{
				conn = DriverManager.getConnection(url, user, password);
				pstmt = conn.prepareStatement(sql);
				
				pstmt.setString(1, dept.getDepartmentName());
				pstmt.setString(2, dept.getLocation());
				pstmt.setString(3, dept.getDepartmentId());
				
				return pstmt.executeUpdate();
				
			}finally{
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
			}
		}
	
	//select
	//매개 변수로 받은 부서_ID의 부서정보를 조회해서 리턴 - 조회결과 row 수 : 1,0
//		왜 리턴 타입이 Department인지를 잘 생각해라
//		이번엔 조회 결과 수가 한줄인 경우만을 가정한다.
		//return 타입은 조회할 레코드의 type이 된다!
		public static Department selectDepartmentById(String departmentId) throws SQLException {
			//1. sql 쿼리 작성(내가 DB에 뭘 요청하고 싶은지? 그걸 생각해서 쓰는 공간이지)
			String sql = "select department_id, department_name, location from department where department_id=?";
			Connection conn = null;
			PreparedStatement pstmt = null;
			//이번엔 조회 결과를 가져올 거니까 다른것과는 달리 ResultSet이 필요하다.
			ResultSet rset = null;
			Department dept = null;
			
			try{
				//1. 연결
				conn = DriverManager.getConnection(url,user,password);
				//2. pstmt 생성
				pstmt = conn.prepareStatement(sql);
				//3. ? 값 치환 작업
				pstmt.setString(1, departmentId);
				rset = pstmt.executeQuery();
				//이 부분 이해하니??
				if(rset.next()){
					dept = new Department(rset.getString(1), rset.getString(2), rset.getString(3));
				}
				return dept;
			}finally{
				if(rset != null) rset.close();
				if(pstmt != null) pstmt.close();
				if(conn != null) conn.close();
			}
		}
	//select
		//모든 부서의 정보를 조회하는 메소드 : 조회 row수 0~n개
		//return type: List(ArrayList)/Map(hashmap)
	public static ArrayList<Department> selectDepartmentList()throws SQLException{
		String sql = "select department_id, department_name,location from department order by department_id";
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rset = null;
		ArrayList<Department> list = new ArrayList<>();
		try{
			//연결 ~ 쿼리 실행
			conn = DriverManager.getConnection(url, user, password);
			pstmt = conn.prepareStatement(sql);
			rset = pstmt.executeQuery();
			
			while(rset.next()){
				list.add(new Department(rset.getString(1),rset.getString(2),rset.getString(3)));
			}
			return list;
		}finally{
			if(rset != null) rset.close();
			if(pstmt != null) pstmt.close();
			if(conn != null) conn.close();
		}
	}
		
}
